using System.Text.Json;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Run((async (HttpContext context) =>
{
    #region Http Request
    
    // Query String
    // await context.Response.WriteAsync(context.Request.QueryString.ToString());
    foreach (var key in context.Request.Query.Keys)
    {
        await context.Response.WriteAsync($"{key}:{context.Request.Query[key]}\r\n");
    }

    if (context.Request.Path.StartsWithSegments("/"))
    {
        context.Response.Headers["Content-Type"] = "text/html";
        
        await context.Response.WriteAsync($"The method is:{context.Request.Method}<br/>");
        await context.Response.WriteAsync($"The Url is:{context.Request.Path}<br/>");

        await context.Response.WriteAsync($"\r\nHeaders:\r\n");
        foreach (var key in context.Request.Headers.Keys)
        {
            await context.Response.WriteAsync($"{key}:{context.Request.Headers[key]}<br/>");
        }
    }
    else if (context.Request.Path.StartsWithSegments("/employees"))
    {
        if (context.Request.Method == "GET")
        {
            if (context.Request.Query.ContainsKey("id"))
            {
                var id = context.Request.Query["id"];
                if (int.TryParse(id, out int employeeId))
                {
                    // Get a particular employee's information
                   var employee= EmployeeRepository.GetEmployeesById(employeeId);
                   if (employee is not null)
                   {
                       await context.Response.WriteAsync($"Name:{employee.Name}<br/>");
                       await context.Response.WriteAsync($"Name:{employee.Position}<br/>");
                       await context.Response.WriteAsync($"Name:{employee.Salary}<br/>");
                   }
                   else
                   {
                       context.Response.StatusCode = 404;
                       await context.Response.WriteAsync("Employee not found！");
                   }
                }
            }
            else
            {
                var employees = EmployeeRepository.GetEmployees();
                foreach (var employee in employees)
                {
                    await context.Response.WriteAsync($"{employee.Name}:{employee.Position}\r\n");
                }

                context.Response.StatusCode = 200;   
            }
        }
        else if (context.Request.Method == "POST")
        {
            using var reader = new StreamReader(context.Request.Body);
            var body = await reader.ReadToEndAsync();
            var employee = JsonSerializer.Deserialize<Employee>(body);

            if (employee is null)
            {
                context.Response.StatusCode = 400;
                return;
            }

            EmployeeRepository.AddEmployee(employee);
            
            context.Response.StatusCode = 201;
            await context.Response.WriteAsync("Employee added successfully");
        }
        else if (context.Request.Method == "PUT")
        {
            using var reader = new StreamReader(context.Request.Body);
            var body = await reader.ReadToEndAsync();
            var employee = JsonSerializer.Deserialize<Employee>(body);

            var result = EmployeeRepository.UpdateEmployee(employee);
            if (result)
            {
                context.Response.StatusCode = 204;
                await context.Response.WriteAsync("Employee updated successfully.");
                return;
            }
            else
            {
                context.Response.StatusCode = 404;
                await context.Response.WriteAsync("Employee not found");
            }
        }
        else if (context.Request.Method == "DELETE")
        {
            if (context.Request.Query.ContainsKey("id"))
            {
                var id = context.Request.Query["id"];
                if (int.TryParse(id, out int employeeId))
                {
                    if (context.Request.Headers["Authorization"] == "frank")
                    {
                        var result = EmployeeRepository.DeleteEmployee(employeeId);
                        if (result)
                        {
                            await context.Response.WriteAsync("Employee is deleted successfully");
                        }
                        else
                        {
                            await context.Response.WriteAsync("Employee not found");
                        }
                    }
                    else
                    {
                        await context.Response.WriteAsync("You are not authorized to delete.");
                    }
                }
            }
        }
    } 
    

    #endregion


    
}


));
app.Run();

static class EmployeeRepository
{
    private static List<Employee> employees = new List<Employee>
    {
        new Employee(1, "John", "Engineer", 6000),
        new Employee(2, "Smith", "Manager", 5000),
        new Employee(3, "Sam", "Technician", 7000),
    };

    public static List<Employee> GetEmployees() => employees;

    public static Employee GetEmployeesById(int id)
    {
        return employees.FirstOrDefault(x => x.Id == id);
    }
    
    public static void AddEmployee(Employee? employee)
    {
        if (employee is not null)
        {
            employees.Add(employee);
        }
    }

    public static bool UpdateEmployee(Employee? employee)
    {
        if (employee is not null)
        {
            var emp = employees.FirstOrDefault(x => x.Id == employee.Id);
            if (emp is not null)
            {
                emp.Name = employee.Name;
                emp.Position = employee.Position;
                emp.Salary = employee.Salary;

                return true;
            }
        }

        return false;
    }

    public static bool DeleteEmployee(int Id)
    {
        var employee = employees.FirstOrDefault(x => x.Id == Id);
        if (employee is not null)
        {
            return true;
        }

        return false;
    }
}


public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }
    public double Salary { get; set; }

    public Employee(int id, string name, string position, double salary)
    {
        Id = id;
        Name = name;
        Position = position;
        Salary = salary;
    }
}